# coding: utf8
# try something like
#from makan import *

def call():
    session.forget()
    return service()

@service.xmlrpc
def test():
    msg='hello'
    return msg

##########################################

def queryXInArea(lat, long, delta, username='', placename=''):
    ''' searches given area for all/filtered people/places''' 
    checkinsList = usersList = []
    checkin = ''
#    delta = 0.1
    if lat:    
        Llat = lat - delta; Rlat = lat + delta
        Dlong = long - delta; Ulong = long + delta
        
        #the query that get all places in the given area 
        query1 = (db.places.lat <= Rlat) & (db.places.lat >= Llat)
        
        query2 = (db.places.long <= Ulong) & (db.places.long >= Dlong)
        
        # to filter places
        if placename:
          query1 = query1 & (db.places.name == placename)
  
        placesSet = db(query1)
        placesList = placesSet(query2).select()

        #get all people in the given area
        for place in placesList:
            if place.checkins:
                for checkinId in place.checkins:
                    checkin = db.checkins[checkinId]
                    user = db.users[checkin.user]
                    if username:
                        if user.first_name == username or user.last_name == username:
                            usersList.append(user)
                    else:
                        usersList.append(user)

    else: 
        usersList = placesList = False
    
    return dict(usersList=usersList, placesList=placesList)

#######################################

def coreAddPlace(place , lat, long, catagId, tags):
   
    tagId = 0
    tagList = []
    t = tags.split() 
    for tag in t :
       tagRow = db(db.tags.name == tag ).select(db.tags.id).first()
      
       if not tagRow :
           tagId = db.tags.insert(name = tag ) 
       else:
           tagId = tagRow.id    
       tagList.append(tagId)
       
    category =  db(db.categories.id == catagId).select().first()
    if category  :
        catagIds =  category.id
    else:
        catagIds = 1
    #add place
    placeid = db.places.insert(name = place ,  long = long, lat = lat, category = catagIds , tags = tagList )
    if placeid :
        msg = "Added"
    else:
        msg= "Error"       
    return msg
    
@service.xmlrpc
def xAddPlace(  place ,   lat , long , catagId, tags):
    added =  jsonString(coreAddPlace(  place, lat , long , catagId,tags))
    return  added

@auth.requires_login()
def addPlace():
      if request.post_vars:
        vars = request.post_vars
        place = vars.name
        long= float(vars.long)
        lat= float(vars.lat)    
        catagId= vars.catagId
        tags = vars.tags
        return dict( added = coreAdd( place , lat , long , catagId, tags))

######################################

@service.xmlrpc
def xSearchPlace(place, lat, long, delta=0.01):
    """
    function is supposed to return JSON formated result of search for a keyword in the domain defined by the long lat
    """
    result = {}
    if lat:
        places = coreSearchPlace(place, lat, long, delta)
        #test
#        result = places
        if places:
            for place in places:
                result[str(place.id)] = place.as_dict()   
        else:
            result = 'no places found!'
    #test
#    result = 'welcome'        
    return str(result)

def searchPlace():
    place = request.get_vars.name
    if request.get_vars.long:
        long = float(request.get_vars.long)
        lat = float(request.get_vars.lat)
        if request.get_vars.delta:
            delta = float(request.get_vars.delta)
        else:
            delta = 0.01
        places = coreSearchPlace(place, lat, long, delta)
        if not places:
            places = 'no places found'
    else:
        places = "Please, enter valid values!"
    
    return dict(places=places)


def coreSearchPlace(place, lat, long, delta):
    if long:
        places = queryXInArea(lat, long, delta, placename=place)['placesList']        
    else:
        places = False
    return places


#def coreSearchPerson(person, lat, long, delta):
#    if long:
#        people = queryXInArea(lat, long, delta, username=person)['usersList']
#    else:
#        people = False
#    return people
#########################################

#working locally
@service.xmlrpc
def xSuggestPlaces(lat, long, delta = 0.01):
    result = {}
    suggestedPlaces = coreSuggestPlaces(lat, long, delta)
    if suggestedPlaces:
        for place in suggestedPlaces:
            result[str(place.id)] = place.as_dict()
    else:
        result = 'no places found'
    return str(result)


def suggestPlaces():
    if request.get_vars:
        lat = float(request.get_vars.lat)
        long = float(request.get_vars.long)
        if request.get_vars.delta:
            delta = float(request.get_vars.delta)
        else:
            delta = 0.01
        suggestedPlaces = coreSuggestPlaces(lat, long, delta)
        if not suggestedPlaces:
            suggestedPlaces = 'no Places found'
    else:
        suggestedPlaces = 'no coordinates found'
    
    return dict(suggestedPlaces = suggestedPlaces)


def coreSuggestPlaces(lat, long, delta):
    if lat:
        suggestedPlaces = queryXInArea(lat, long, delta)['placesList']
        suggestedPlaces = suggestedPlaces[:3]
    else:
        suggestedPlaces = False
          
    return suggestedPlaces

#####################################################

@service.xmlrpc
def xSearchAll(keyword, lat, long, delta = 0.01):
    result1 = result2 = all = {}
    if lat:
        people, places = coreSearchAll(lat, long, keyword, delta)
        if people:
            for user in people:
                result1[str(user.id)] = user.as_dict()
        else:
            result1 = 'no people found'
            
        if places:
            for place in places:
                result2[str(place.id)] = place.as_dict()
        else:
            result2 = 'no places found'
        
        all["people"] = result1; all["places"] = result2
    else:
        all = 'enter coordinates'
    return str(all)

def searchAll():
    keyword = request.get_vars.keyword
    if request.get_vars:
        lat = float(request.get_vars.lat)
        long = float(request.get_vars.long)
        if request.get_vars.delta:
            delta = float(request.get_vars.delta)
        else:
            delta = 0.01
        people, places = coreSearchAll(lat, long, keyword, delta)

        if not people: people = 'no people found'
        if not places: places = 'no places found'
    else:
        places = people = 'enter coordinates'

    return dict(people=people, places=places)

def coreSearchAll(lat, long, keyword, delta):
    people = places = False
    if lat:
        people = queryXInArea(lat, long, delta, username=keyword)['usersList']
        places = queryXInArea(lat, long, delta, placename=keyword)['placesList']
    else:
        people = places = False

    return (people, places)

#####################################################################################

#TODO: add using place id not lag and long
def coreAddPlaceToFav(uid, lat, long):

    user = db.users[uid]
    if not user: return T("bad user id")

    place = db(db.places.long == float(long) and db.places.lat == float(lat)).select()
    if not place: return T("place not found")
    place = place[0]

    favPlaces = user.fav_places
    if place.id in favPlaces:
        return T("already in favourites")
    else:
        favPlaces.append(place.id)
        user.update_record(fav_places = favPlaces)
        return T("done")

@auth.requires_login()
def addPlaceToFav():
    uid = auth.user.id
    long = request.args[0]
    lat = request.args[1]
    return coreAddPlaceToFav(uid, lat, long)

@service.xmlrpc
def xAddPlaceToFav(uid, lat, long):
    msg = coreAddPlaceToFav(uid, lat, long)
    return jsonString(msg)

###############################################################################

#TODO: change lat and long to place id
def coreRemovePlaceFromFav(uid, lat, long):

    user = db.users[uid]
    if not user: return T("bad user id")

    place = db(db.places.long == long and db.places.lat == lat).select()
    if not place: return T("palce not found")
    place = place[0]

    favPlaces = user.fav_places
    if place.id in favPlaces:
        favPlaces.remove(place.id)
        user.update_record(fav_places = favPlaces)
        return T("done")
    else:
        
        return T("not in favourites")

@auth.requires_login()
def removePlaceFromFav():
    uid = auth.user.id
    long = request.args[0]
    lat = request.args[1]
    return coreRemovePlaceFromFav(uid, lat, long)

@service.xmlrpc
def xRemovePlaceFromFav(uid, lat, long):
    msg = coreRemovePlaceFromFav(uid, lat, long)
    return jsonString(msg)

#################################################################################

#TODO: like with place id not lag and long 
def coreLikePlace(uid, lat, long):
    user = db.users[uid]
    if not user: return T("bad user id")

    place = db(db.places.long == float(long) and db.places.lat == float(lat)).select()
    if not place: return T("palce not found")
    place = place[0]

    likedPlaces = user.liked_places
    if place.id in likedPlaces:
        return T("already like")
    else:
        likedPlaces.append(place.id)
        user.update_record(liked_places = likedPlaces)

        likes = int(place.likes)
        likes += 1
        place.update_record(likes = likes)
        return T("done")

@auth.requires_login()
def likePlace():
    uid = auth.user.id
    long = request.args[0]
    lat = request.args[1]
    return coreLikePlace(uid, lat, long)

@service.xmlrpc
def xLikePlace(uid, lat, long):
    msg = coreLikePlace(uid, lat, long)
    return jsonString(msg)

###################################################################################

#TODO: unlike with place id not lag and long
def coreUnLikePlace(uid, lat, long):
    user = db.users[uid]
    if not user: return T("bad user id")

    place = db(db.places.long == float(long) and db.places.lat == float(lat)).select()
    if not place: return T("palce not found")
    place = place[0]

    likedPlaces = user.liked_places
    if place.id in likedPlaces:
        likedPlaces.remove(place.id)
        user.update_record(liked_places = likedPlaces)

        likes = int(place.likes)
        likes -= 1
        place.update_record(likes = likes)
        return T("done")
    else:
        return T("not in liked places")

@auth.requires_login()
def unLikePlace():
    uid = auth.user.id
    long = request.args[0]
    lat = request.args[1]
    return coreUnLikePlace(uid, lat, long)

@service.xmlrpc
def xUnLikePlace(uid, lat, long):
    msg = coreUnLikePlace(uid, lat, long)
    return jsonString(msg)

##################################################################################

